# coding=utf-8
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from fbprophet import Prophet
from pandas import Timestamp


def run_fb(seasonality_prior_scale=10.0,
           changepoint_prior_scale=0.05,
           mcmc_samples=0,  # lots of error
           interval_width=0.80,
           n_changepoints=25,
           holidays_prior_scale=10.0,
           algorithm="BFGS"):  # no effect
    weekly_seasonality = False
    yearly_seasonality = True
    daily_seasonality = False
    holidays = None
    growth = 'linear'

    m = Prophet(weekly_seasonality=weekly_seasonality,
                yearly_seasonality=yearly_seasonality,
                daily_seasonality=daily_seasonality,
                holidays=holidays,
                seasonality_prior_scale=seasonality_prior_scale,
                changepoint_prior_scale=changepoint_prior_scale,
                mcmc_samples=mcmc_samples,
                n_changepoints=n_changepoints,
                holidays_prior_scale=holidays_prior_scale,
                interval_width=interval_width,
                growth=growth)

    a = [[Timestamp('2016-03-07 00:00:00'), 100, 4225.0, 0],
         [Timestamp('2016-03-14 00:00:00'), 100, 4225.0, 0],
         [Timestamp('2016-03-21 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-03-28 00:00:00'), 2200, 4225.0, 0],
         [Timestamp('2016-04-04 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-04-11 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-04-18 00:00:00'), 50, 4225.0, 0],
         [Timestamp('2016-04-25 00:00:00'), 300, 4225.0, 0],
         [Timestamp('2016-05-02 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-05-09 00:00:00'), 100, 4225.0, 0],
         [Timestamp('2016-05-16 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-05-23 00:00:00'), 150, 4225.0, 0],
         [Timestamp('2016-05-30 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-06-06 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-06-13 00:00:00'), 100, 4225.0, 0],
         [Timestamp('2016-06-20 00:00:00'), 100, 4225.0, 0],
         [Timestamp('2016-06-27 00:00:00'), 100, 4225.0, 0],
         [Timestamp('2016-07-04 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-07-11 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-07-18 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-07-25 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-08-01 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-08-08 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-08-15 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-08-22 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-08-29 00:00:00'), 2360, 4225.0, 0],
         [Timestamp('2016-09-05 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-09-12 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-09-19 00:00:00'), 50, 4225.0, 0],
         [Timestamp('2016-09-26 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-10-03 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-10-10 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-10-17 00:00:00'), 1000, 4225.0, 0],
         [Timestamp('2016-10-24 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-10-31 00:00:00'), 50, 4225.0, 0],
         [Timestamp('2016-11-07 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-11-14 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-11-21 00:00:00'), 1100, 4225.0, 0],
         [Timestamp('2016-11-28 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-12-05 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-12-12 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-12-19 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2016-12-26 00:00:00'), 3000, 4225.0, 0],
         [Timestamp('2017-01-02 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2017-01-09 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2017-01-16 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2017-01-23 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2017-01-30 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2017-02-06 00:00:00'), 2500, 4225.0, 0],
         [Timestamp('2017-02-13 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2017-02-20 00:00:00'), 1500, 4225.0, 0],
         [Timestamp('2017-02-27 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2017-03-06 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2017-03-13 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2017-03-20 00:00:00'), 2500, 4225.0, 0],
         [Timestamp('2017-03-27 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2017-04-03 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2017-04-10 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2017-04-17 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2017-04-24 00:00:00'), 3250, 4225.0, 0],
         [Timestamp('2017-05-01 00:00:00'), 0, 4225.0, 0],
         [Timestamp('2017-05-08 00:00:00'), 0, 4225.0, 0]]
    df = pd.DataFrame(a)
    df = df.rename(columns={0: 'ds',  # 实际的列名为数字，而不是字符串
                            1: 'y',  # 使用 '0': 'uid'来改列名是改不了的
                            2: 'cap',
                            3: 'floor'})
    print(df)
    m.fit(df, algorithm=algorithm)
    print('fit ---- end')

    future = m.make_future_dataframe(periods=26,
                                     freq='w')  # Predict
    future['cap'] = float(4225.0)  # Not only df but also future should has cap columns
    future['floor'] = 0
    forecast_df = m.predict(future)
    # m.plot(forecast_df)
    # plt.show()
    return forecast_df['yhat'].values.tolist(), forecast_df


def test_2():
    df = pd.read_csv('data/example_wp_peyton_manning.csv')
    df['y'] = np.log(df['y'])
    df.head()
    m = Prophet()
    m.fit(df)
    future = m.make_future_dataframe(periods=365)
    future.tail()
    forecast = m.predict(future)
    forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()
    m.plot(forecast).show()
    m.plot_components(forecast).show()
    plt.show()


list1, forecast_df1 = run_fb()
list2, forecast_df2 = run_fb(algorithm="BFGS")

# n_changepoints=26 (default 25)     for -8.494753 ~ 11.157635

# seasonality_prior_scale=10.0000001 for -0.013423 ~ 0.010187
# seasonality_prior_scale=10.000001  for -0.012161 ~ 0.012158
# seasonality_prior_scale=10.1       for -1.638588 ~ 1.525623

# holidays_prior_scale=10.0          for 0 for no holidays

# changepoint_prior_scale=0.05000001 for -0.261294 ~ 0.257016
#                                    Sometimes:
# mcmc_samples=1 ___________________ UnboundLocalError: local variable 'pool' referenced before assignment

# internal_val _____________________ will dead

# uncertainty_samples=1001 _________ will dead

df_result = pd.DataFrame({'list': list1,
                          'list_change': list2})
df_result['diff'] = df_result['list'] - df_result['list_change']
print(df_result)
print(df_result.sort_values('diff'))
